#pragma once

#include "zqdb.h"
#include "zqstr.hpp"
#include "zqdb.pb.h"
#include "mdbdf.hpp"

namespace zqdb {

	template<class TPBCodeInfo, class TCODEINFO>
	inline size_t UpdateCodeInfo(HZQDB h, const TPBCodeInfo& one, TCODEINFO* data, MDB_FIELD* field)
	{
		size_t field_num = 0;
		for (auto val : one.values())
		{
			field[field_num].index = val.id();
			ZQDBNormalizeField(h, field + field_num, 1);
			auto varvalue = val.value();
			switch (field[field_num].type)
			{
			case MDB_FIELD_TYPE_CHAR: {
				*((char*)data + field[field_num].offset) = (char)varvalue.u32();
			} break;
			case MDB_FIELD_TYPE_BYTE: {
				*(byte*)((char*)data + field[field_num].offset) = (byte)varvalue.u32();
			} break;
			case MDB_FIELD_TYPE_INT16: {
				*(int16_t*)((char*)data + field[field_num].offset) = (int16_t)varvalue.u32();
			} break;
			case MDB_FIELD_TYPE_UINT16: {
				*(uint16_t*)((char*)data + field[field_num].offset) = (uint16_t)varvalue.u32();
			} break;
			case MDB_FIELD_TYPE_INT32: {
				*(int32_t*)((char*)data + field[field_num].offset) = varvalue.i32();
			} break;
			case MDB_FIELD_TYPE_UINT32: {
				*(uint32_t*)((char*)data + field[field_num].offset) = varvalue.u32();
			} break;
			case MDB_FIELD_TYPE_INT64: {
				*(int64_t*)((char*)data + field[field_num].offset) = varvalue.i64();
			} break;
			case MDB_FIELD_TYPE_UINT64: {
				*(uint64_t*)((char*)data + field[field_num].offset) = varvalue.u64();
			} break;
			case MDB_FIELD_TYPE_FLOAT: {
				*(float*)((char*)data + field[field_num].offset) = varvalue.f32();
			} break;
			case MDB_FIELD_TYPE_DOUBLE: {
				*(double*)((char*)data + field[field_num].offset) = varvalue.f64();
			} break;
			case MDB_FIELD_TYPE_STRING: {
				strncpy((char*)data + field[field_num].offset, varvalue.str().c_str(), field[field_num].size);
			} break;
			default: {
				memcpy((char*)data + field[field_num].offset, varvalue.data().data(), std::min<>((size_t)field[field_num].size, varvalue.data().size()));
			} break;
			}
			field_num++;
		}
		return field_num;
	}

	template<class TPBCodeInfo, class TCODEINFO>
	inline void UpdateCodeInfoNoID(HZQDB h, const TPBCodeInfo& one, TCODEINFO* data, MDB_FIELD* field, size_t field_num)
	{
		ASSERT(one.values_size() == field_num);
		for (size_t i = 0; i < field_num; i++)
		{
			const auto& val = one.values(i);
			switch (field[i].type)
			{
			case MDB_FIELD_TYPE_CHAR: {
				*((char*)data + field[i].offset) = (char)val.u32();
			} break;
			case MDB_FIELD_TYPE_BYTE: {
				*(byte*)((char*)data + field[i].offset) = (byte)val.u32();
			} break;
			case MDB_FIELD_TYPE_INT16: {
				*(int16_t*)((char*)data + field[i].offset) = (int16_t)val.u32();
			} break;
			case MDB_FIELD_TYPE_UINT16: {
				*(uint16_t*)((char*)data + field[i].offset) = (uint16_t)val.u32();
			} break;
			case MDB_FIELD_TYPE_INT32: {
				*(int32_t*)((char*)data + field[i].offset) = val.i32();
			} break;
			case MDB_FIELD_TYPE_UINT32: {
				*(uint32_t*)((char*)data + field[i].offset) = val.u32();
			} break;
			case MDB_FIELD_TYPE_INT64: {
				*(int64_t*)((char*)data + field[i].offset) = val.i64();
			} break;
			case MDB_FIELD_TYPE_UINT64: {
				*(uint64_t*)((char*)data + field[i].offset) = val.u64();
			} break;
			case MDB_FIELD_TYPE_FLOAT: {
				*(float*)((char*)data + field[i].offset) = val.f32();
			} break;
			case MDB_FIELD_TYPE_DOUBLE: {
				*(double*)((char*)data + field[i].offset) = val.f64();
			} break;
			case MDB_FIELD_TYPE_STRING: {
				strncpy((char*)data + field[i].offset, val.str().c_str(), field[i].size);
			} break;
			default: {
				memcpy((char*)data + field[i].offset, val.data().data(), std::min<size_t>(field[i].size, val.data().size()));
			} break;
			}
		}
	}

	template<class TPBCodeInfo, class TCODEINFO>
	inline void BuildCodeInfo(TPBCodeInfo* one, const TCODEINFO* data, MDB_FIELD* field, size_t field_num)
	{
		one->set_exchange(data->Exchange);
		one->set_code(data->Code);
		for (size_t i = 0; i < field_num; i++)
		{
			auto val = one->add_values();
			val->set_id(field[i].index);
			auto varval = val->mutable_value();
			switch (field[i].type)
			{
			case MDB_FIELD_TYPE_CHAR: {
				varval->set_u32(*(char*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_BYTE: {
				varval->set_u32(*(uint8_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_INT16: {
				varval->set_u32(*(int16_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_UINT16: {
				varval->set_u32(*(uint16_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_INT32: {
				varval->set_i32(*(int32_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_UINT32: {
				varval->set_u32(*(uint32_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_INT64: {
				varval->set_i64(*(int64_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_UINT64: {
				varval->set_u64(*(uint64_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_FLOAT: {
				varval->set_f32(*(float*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_DOUBLE: {
				varval->set_f64(*(double*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_STRING: {
				varval->set_str((const char*)data + field[i].offset, field[i].size);
			} break;
			default: {
				varval->set_data((const char*)data + field[i].offset, field[i].size);
			} break;
			}
		}
	}

	template<class TPBCodeInfo, class TCODEINFO>
	inline void BuildCodeInfoNoID(TPBCodeInfo* one, const TCODEINFO* data, MDB_FIELD* field, size_t field_num)
	{
		one->set_exchange(data->Exchange);
		one->set_code(data->Code);
		for (size_t i = 0; i < field_num; i++)
		{
			auto val = one->add_values();
			switch (field[i].type)
			{
			case MDB_FIELD_TYPE_CHAR: {
				val->set_u32(*(char*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_BYTE: {
				val->set_u32(*(uint8_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_INT16: {
				val->set_u32(*(int16_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_UINT16: {
				val->set_u32(*(uint16_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_INT32: {
				val->set_i32(*(int32_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_UINT32: {
				val->set_u32(*(uint32_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_INT64: {
				val->set_i64(*(int64_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_UINT64: {
				val->set_u64(*(uint64_t*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_FLOAT: {
				val->set_f32(*(float*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_DOUBLE: {
				val->set_f64(*(double*)((const char*)data + field[i].offset));
			} break;
			case MDB_FIELD_TYPE_STRING: {
				val->set_str((const char*)data + field[i].offset, field[i].size);
			} break;
			default: {
				val->set_data((const char*)data + field[i].offset, field[i].size);
			} break;
			}
		}
	}

	template<class TIDS>
	inline void BuildField(HZQDB h, MDB_FIELD* field, const TIDS& ids, size_t count) {
		for (size_t i = 0; i < count; i++)
		{
			field[i].index = ids[i];
		}
		ZQDBNormalizeField(h, field, count);
	}

	inline size_t BuildFullDiffField(MDB_FIELD* diff_field) {
		size_t diff_field_num = 0;
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, DATE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, TIME);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, YCLOSE);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, YSETTLE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, OPEN);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, HIGH);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, LOW);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, CLOSE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, SETTLE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, AMOUNT);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, VOLUME);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BID1);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BID2);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BID3);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BID4);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BID5);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BIDV1);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BIDV2);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BIDV3);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BIDV4);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, BIDV5);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASK1);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASK2);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASK3);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASK4);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASK5);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASKV1);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASKV2);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASKV3);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASKV4);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, CODE, ASKV5);
		return diff_field_num;
	}

	inline size_t BuildFullFTDiffField(MDB_FIELD* diff_field) {
		size_t diff_field_num = 0;
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, DATE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, TIME);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, YCLOSE);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, YSETTLE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, OPEN);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, HIGH);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, LOW);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, CLOSE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, SETTLE);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, AMOUNT);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, VOLUME);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BID1);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BID2);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BID3);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BID4);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BID5);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BIDV1);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BIDV2);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BIDV3);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BIDV4);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, BIDV5);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASK1);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASK2);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASK3);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASK4);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASK5);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASKV1);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASKV2);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASKV3);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASKV4);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, ASKV5);
		//diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, PreOpenInterest);
		diff_field[diff_field_num++] = MDB_FIELD_TABLE_FIELD(ZQDB, FTCODE, OpenInterest);
		return diff_field_num;
	}

	template<class TSubs, class TCODEINFO = CODEINFO>
	inline bool BuildFullRtnSubscribeData(com::zqdb::proto::msg::RtnSubscribe& rtn, const TSubs& subs) {
		MDB_FIELD diff_field[256] = { 0 };
		size_t diff_field_num = BuildFullDiffField(diff_field);
		if (diff_field_num > 0) {
			for (auto h : subs) {
				BuildCodeInfo(rtn.add_codes(), (TCODEINFO*)ZQDBGetValue(h), diff_field, diff_field_num);
			}
			return true;
		}
		return false;
	}

	template<class TCODEINFO = CODEINFO>
	inline bool BuildFullRtnSubscribeData(com::zqdb::proto::msg::RtnSubscribe& rtn, TCODEINFO* newdata) {
		MDB_FIELD diff_field[256] = { 0 };
		size_t diff_field_num = BuildFullDiffField(diff_field);
		if (diff_field_num > 0) {
			BuildCodeInfo(rtn.add_codes(), newdata, diff_field, diff_field_num);
			return true;
		}
		return false;
	}

	template<class TSubs, class TCODEINFO = FTCODEINFO>
	inline bool BuildFullFTRtnSubscribeData(com::zqdb::proto::msg::RtnSubscribe& rtn, const TSubs& subs) {
		MDB_FIELD diff_field[256] = { 0 };
		size_t diff_field_num = BuildFullFTDiffField(diff_field);
		if (diff_field_num > 0) {
			for (auto h : subs) {
				BuildCodeInfo(rtn.add_codes(), (TCODEINFO*)ZQDBGetValue(h), diff_field, diff_field_num);
			}
			return true;
		}
		return false;
	}

	template<class TCODEINFO = FTCODEINFO>
	inline bool BuildFullFTRtnSubscribeData(com::zqdb::proto::msg::RtnSubscribe& rtn, TCODEINFO* newdata) {
		MDB_FIELD diff_field[256] = { 0 };
		size_t diff_field_num = BuildFullFTDiffField(diff_field);
		if (diff_field_num > 0) {
			BuildCodeInfo(rtn.add_codes(), newdata, diff_field, diff_field_num);
			return true;
		}
		return false;
	}

	template<class TCODEINFO = CODEINFO>
	inline bool BuildDiffRtnSubscribeData(com::zqdb::proto::msg::RtnSubscribe& rtn
		, const MDB_FIELD* field, size_t field_num, TCODEINFO* newdata, TCODEINFO* olddata) {
		MDB_FIELD diff_field[256] = { 0 };
		size_t diff_field_num = mdb::FieldOp::Diff(field, field_num, (const char*)newdata, (const char*)olddata, diff_field);
		if (diff_field_num > 0) {
			BuildCodeInfo(rtn.add_codes(), newdata, diff_field, diff_field_num);
			return true;
		}
		return false;
	}

	inline void BuildStdTableMsg(zqdb::Msg& msg, const MDB_FIELD* field, size_t field_num, HZQDB* elem_data, size_t elem_num) {
		size_t elem_sz = MDBFieldCalcSize(field, field_num);
		if (elem_sz) {
			com::mdb::proto::msg::StdTable table;
			auto elem_attr = table.mutable_attr();
			for (size_t i = 0; i < field_num; i++)
			{
				auto col_attr = elem_attr->Add();
				col_attr->set_id(field[i].index);
				col_attr->set_type(field[i].type);
				col_attr->set_size(field[i].size);
			}
			if (elem_num) {
				auto mutable_data = table.mutable_data();
				for (size_t i = 0; i < field_num; i++)
				{
					auto col_data = mutable_data->Add();
					for (size_t j = 0; j < elem_num; j++)
					{
						auto elem_data_ptr = (const char*)ZQDBGetValue(elem_data[j]);
						switch (field[i].type)
						{
						case MDB_FIELD_TYPE_CHAR: {
							col_data->mutable_u32()->add_u32(*(char*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_BYTE: {
							col_data->mutable_u32()->add_u32(*(byte*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_INT16: {
							col_data->mutable_u32()->add_u32(*(int16_t*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_UINT16: {
							col_data->mutable_u32()->add_u32(*(uint16_t*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_INT32: {
							col_data->mutable_i32()->add_i32(*(int32_t*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_UINT32: {
							col_data->mutable_u32()->add_u32(*(uint32_t*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_INT64: {
							col_data->mutable_i64()->add_i64(*(int64_t*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_UINT64: {
							col_data->mutable_u64()->add_u64(*(uint64_t*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_FLOAT: {
							col_data->mutable_f32()->add_f32(*(float*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_DOUBLE: {
							col_data->mutable_f64()->add_f64(*(double*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_STRING: {
							col_data->mutable_str()->add_str((const char*)(elem_data_ptr + field[i].offset));
						} break;
						case MDB_FIELD_TYPE_BLOB: {
							col_data->mutable_str()->add_str((const char*)(elem_data_ptr + field[i].offset), field[i].size);
						} break;
						default: {
						} break;
						}
					}
				}
			}
			auto data = table.SerializeAsString();
			msg.SetData(data.data(), data.size());
			msg.SetParamAsUInt("elem_sz", elem_sz);
			msg.SetParamAsUInt("elem_num", elem_num);
		}
		else {
			msg.SetParamAsUInt("elem_sz", elem_sz);
			msg.SetParamAsUInt("elem_num", elem_num);
		}
	}

	inline void BuildDataMsg(zqdb::Msg& msg, HZQDB h, PERIODTYPE cycle, const MDB_FIELD* field, size_t field_num) {
		size_t elem_sz = 0;
		size_t elem_num = ZQDBGetDataCount(h, cycle, 0, &elem_sz);
		if (elem_sz && elem_num) {
			if (1) {
				com::mdb::proto::msg::StdTable table;
				auto elem_attr = table.mutable_attr();
				for (size_t i = 0; i < field_num; i++)
				{
					auto col_attr = elem_attr->Add();
					col_attr->set_id(field[i].index);
					col_attr->set_type(field[i].type);
					col_attr->set_size(field[i].size);
				}
				auto elem_data = table.mutable_data();
				for (size_t i = 0; i < field_num; i++)
				{
					auto col_ptr = ZQDBGetDataValueEx(h, cycle, (MDB_FIELD*)field + i);
					auto col_data = elem_data->Add();
					for (size_t j = 0; j < elem_num; j++)
					{
						switch (field[i].type)
						{
						case MDB_FIELD_TYPE_CHAR: {
							col_data->mutable_u32()->add_u32(((char*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_BYTE: {
							col_data->mutable_u32()->add_u32(((byte*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_INT16: {
							col_data->mutable_u32()->add_u32(((int16_t*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_UINT16: {
							col_data->mutable_u32()->add_u32(((uint16_t*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_INT32: {
							col_data->mutable_i32()->add_i32(((int32_t*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_UINT32: {
							col_data->mutable_u32()->add_u32(((uint32_t*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_INT64: {
							col_data->mutable_i64()->add_i64(((int64_t*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_UINT64: {
							col_data->mutable_u64()->add_u64(((uint64_t*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_FLOAT: {
							col_data->mutable_f32()->add_f32(((float*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_DOUBLE: {
							col_data->mutable_f64()->add_f64(((double*)col_ptr)[j]);
						} break;
						case MDB_FIELD_TYPE_STRING: {
							col_data->mutable_str()->add_str(((const char*)col_ptr) + j * field[i].size);
						} break;
						case MDB_FIELD_TYPE_BLOB: {
							col_data->mutable_str()->add_str(((const char*)col_ptr) + j * field[i].size, field[i].size);
						} break;
						default: {
						} break;
						}
					}
				}
				auto data = table.SerializeAsString();
				msg.SetData(data.data(), data.size());
				msg.SetParamAsUInt("elem_sz", elem_sz);
				msg.SetParamAsUInt("elem_num", elem_num);
			}
			else {
				com::mdb::proto::msg::Table table;
				auto elem_data = table.mutable_data();
				elem_data->reserve(elem_sz * elem_num);
				size_t i = 0;
				for (; i < elem_num; i++)
				{
					char data[2048] = { 0 }; 
					ASSERT(elem_sz <= sizeof(data));
					size_t num = 1;
					ZQDBGetDataValue(h, cycle, 0, i, &num, &data);
					if (num != 1) {
						break;
					}
					elem_data->append((const char*)&data, elem_sz);
				}
				auto data = table.SerializeAsString();
				msg.SetData(data.data(), data.size());
				msg.SetParamAsUInt("elem_sz", elem_sz);
				msg.SetParamAsUInt("elem_num", i);
			}
		}
		else {
			msg.SetParamAsUInt("elem_sz", elem_sz);
			msg.SetParamAsUInt("elem_num", elem_num);
		}
	}
}
